package com.foreveross.crawl.adapter.sub.impl20140402.v3;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.io.FileUtils;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.foreveross.crawl.adapter.AbstractAdapter;
import com.foreveross.crawl.adapter.PlaneInfoEntityBuilder;
import com.foreveross.crawl.common.exception.self.UnableParseRouteTypeException;
import com.foreveross.crawl.common.util.RandomBrowserVersion;
import com.foreveross.crawl.domain.airfreight.AbstractPlaneInfoEntity;
import com.foreveross.crawl.domain.airfreight.CabinEntity;
import com.foreveross.crawl.domain.airfreight.doub.DoublePlaneInfoEntity;
import com.foreveross.crawl.domain.airfreight.doub.ReturnCabinEntity;
import com.foreveross.crawl.domain.airfreight.doub.ReturnDoublePlaneInfoEntity;
import com.foreveross.crawl.domain.airfreight.single.SinglePlaneInfoEntity;
import com.foreveross.crawl.exception.FlightInfoNotFoundException;
import com.foreveross.taskservice.common.bean.TaskModel;
import com.google.common.collect.Lists;

/**
 * 春秋航空官网数据抓取适配器。
 * 
 * @author luomingliang@foreveross.com
 * @date 2014.07.04
 * @version 1.0.0
 */
@SuppressWarnings({ "unchecked", "deprecation" })
public class SpringtourAirportAdapter extends AbstractAdapter {
	private static Logger log = LoggerFactory.getLogger(SpringtourAirportAdapter.class);

	public SpringtourAirportAdapter(TaskModel taskQueue) {
		super(taskQueue);
	}

	@Override
	public String getUrl() throws Exception {
		return null;
	}

	/**
	 * 获取请求参数。
	 * 
	 * @param isReturn 是否单程
	 */
	private Map<String, String> getParamMap(Boolean isReturn) {
		//OriCityCode=SHA&DestCityCode=PEK&FlightDate=2014-10-18&MoneyType=0&IsReturn=false&FlightDateReturn=2014-10-19
		Map<String, String> p = new HashMap<String, String>();
		p.put("OriCityCode", taskQueue.getFromCity());
		p.put("DestCityCode", taskQueue.getToCity());
		p.put("FlightDate", taskQueue.getFlightDate());
		p.put("FlightDateReturn", taskQueue.getReturnGrabDate());
		p.put("IsReturn", isReturn.toString());
		p.put("MoneyType", "0");
		return p;
	}

	private void setRequestHeader() throws Exception {
		HttpGet get = null;
		String url = null;
		try {
			url = getBaseGetUrl("http://www.china-sss.com/AirFlights/SearchFlights", getParamMap(false));
			url = url.concat("AdultNum=0&ChildNum=0&InfantNum=0");
			get = new HttpGet(url);
			get.setHeader("Host", "www.china-sss.com");
			get.setHeader("User-Agent", RandomBrowserVersion.getBV().getUserAgent());
			get.setHeader("Accept", "application/json, text/javascript, */*");
			get.setHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
			get.setHeader("Referer", url);
			super.excuteRequest(get);
		} finally {
			if(get != null) get.releaseConnection();
			get = null;
			url = null;
		}
	}

	private String getFetchUrl(Boolean isReturn) throws Exception {
		String url = "http://www.china-sss.com/AirFlights/SearchByTime";
		return super.getBaseGetUrl(url, getParamMap(isReturn));
	}

	private Object fetchPageData(Boolean isReturn) throws Exception {
		HttpRequestBase request = null;
		String page;
		try {
			request = new HttpPost(getFetchUrl(isReturn));
			request.setHeader("Host", "www.china-sss.com");
			request.setHeader("User-Agent", RandomBrowserVersion.getBV().getUserAgent());
			request.setHeader("Accept", "application/json, text/javascript, */*");
			request.setHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
			request.setHeader("Referer", "http://www.china-sss.com/AirFlights/SearchFlights");
			page = super.excuteRequest(request);
			super.appendPageContents(page);
			return JSONObject.fromObject(page);
		} finally {
			if(request != null) request.releaseConnection();
			request = null;
			page = null;
		}

	}

	@Override
	public Object fetch(String url) throws Exception {
		this.setRequestHeader();
		return fetchPageData(false);
	}

	@Override
	public boolean validateFetch(Object fetchObject) throws Exception {
		JSONObject jsonObject = (JSONObject) fetchObject;
		JSONArray flights = jsonObject.getJSONArray("Flights");
		if (flights.size() <= 0) {
			throw new FlightInfoNotFoundException("没有找到航班");
		}
		return true;
	}

	@Override
	public List<Object> paraseToVo(Object obj) throws Exception {
		log.debug(String.format("正在解析[%s]的[%s]的数据.", "春秋航空", getRouteType().getName()));
		switch (getRouteType()) {
		case DOMESTIC_ONEWAYTRIP:
		case INTERNATIONAL_ONEWAY:
			return (List<Object>) paraseOneWay(obj);
		case DOMESTIC_ROUNDTRIP:
		case INTERNATIONAL_ROUND:
			return (List<Object>) paraseRoundTrip(obj);
		default:
			throw new UnableParseRouteTypeException("春秋航空", getRouteType().getName());
		}
	}

	private <T extends AbstractPlaneInfoEntity> List<AbstractPlaneInfoEntity> buildPlaneInfoEntitys(JSONObject jsonObj, Class<T> clazz) throws Exception {
		List<AbstractPlaneInfoEntity> results = Lists.newArrayList();
		AbstractPlaneInfoEntity plane = null;
		JSONArray flights = jsonObj.getJSONArray("Flights");
		for (int i = 0; i < flights.size(); i++) {
			JSONObject jsonFlight = flights.getJSONObject(i);
			//String segHeadId = jsonFlight.getString("SegHeadId");
			String companeyCode = jsonFlight.getString("CompanyCode");
			String companyName = jsonFlight.getString("CompanyName");
			String flightNo = jsonFlight.getString("FlightNo");
			String acType = jsonFlight.getString("AcType");
			String oriTimeBJ = jsonFlight.getString("OriTimeBJ");
			String destTimeBJ = jsonFlight.getString("DestTimeBJ");
			if (clazz.equals(SinglePlaneInfoEntity.class) || clazz.equals(DoublePlaneInfoEntity.class)) {
				plane = PlaneInfoEntityBuilder.buildPlaneInfo(taskQueue, companeyCode, companyName, companyName, oriTimeBJ, destTimeBJ, flightNo, jsonFlight.getString("Price"), null, jsonFlight.getString("Price"), acType);
			} else {
				plane = PlaneInfoEntityBuilder.buildPlaneInfo(taskQueue, companeyCode, companyName, companyName, oriTimeBJ, destTimeBJ, flightNo, jsonFlight.getString("Price"), null, jsonFlight.getString("Price"), acType, ReturnDoublePlaneInfoEntity.class);
			}
			log.info(String.format("成功构建[%s]实体。", plane.getFlightNo()));
			//setCabins(segHeadId, plane);
			log.info(String.format("实体[%s]仓位组装完成。", plane.getFlightNo()));
			results.add(plane);
		}
		return results;
	}

	/** 解析单程。 */
	private Object paraseOneWay(Object obj) throws Exception {
		long starttime = System.currentTimeMillis();
		log.info("正在解析数据...");
		List<AbstractPlaneInfoEntity> singles = Lists.newArrayList();
		singles = buildPlaneInfoEntitys((JSONObject) obj, SinglePlaneInfoEntity.class);
		long endtime = System.currentTimeMillis();
		log.info(String.format("解析数据成功.耗时：%s", endtime - starttime));
		return singles;
	}

	/** 解析往返。 */
	private Object paraseRoundTrip(Object obj) throws Exception {
		long starttime = System.currentTimeMillis();
		log.info("正在解析往返数据...");
		List<AbstractPlaneInfoEntity> doubles = Lists.newArrayList();
		List returns = Lists.newArrayList();
		doubles = buildPlaneInfoEntitys((JSONObject) obj, DoublePlaneInfoEntity.class);
		JSONObject returnObj = (JSONObject) fetchPageData(true); // 获取回程数据
		returns = buildPlaneInfoEntitys(returnObj, ReturnDoublePlaneInfoEntity.class);
		for (AbstractPlaneInfoEntity db : doubles) {
			PlaneInfoEntityBuilder.getDoubleEntity(db).getReturnPlaneInfos().addAll(returns);
		}
		PlaneInfoEntityBuilder.buildRelation(doubles, returns);
		PlaneInfoEntityBuilder.buildLimitPrice(doubles);
		long endtime = System.currentTimeMillis();
		log.info(String.format("解析往返数据成功.耗时：%s", endtime - starttime));
		return doubles;
	}

	/** 设置仓位。 */
	private <T extends AbstractPlaneInfoEntity> void setCabins(String segHeadId, T plane) throws Exception {
		String[] seats = { "SW", "A", "B" };
		for (Object val : seats) {
			JSONArray cabins = getCabinDatas(segHeadId, val.toString());
			for (int j = 0; j < cabins.size(); j++) {
				JSONObject cabin = cabins.getJSONObject(j);
				String cabinName = getSeatName(val.toString());
				JSONObject cabinDetail = getCabinPriceDetail(cabin.getString("Name"), segHeadId);
				String cabinType = cabinDetail.getString("GoAdultCabin");
				Double price = PlaneInfoEntityBuilder.getDouble(cabinDetail.getString("GoAdultPrice"));
				Double tax1 = PlaneInfoEntityBuilder.getDouble(cabinDetail.getString("GoAdultPortPay"));
				Double tax2 = PlaneInfoEntityBuilder.getDouble(cabinDetail.getString("GoAdultFuelFee"));
				Double tax = tax1 + tax2;
				Double total = tax + price;

				// Double price = PlaneInfoEntityBuilder.getDouble(cabin.getString("Price"));
				if (plane instanceof SinglePlaneInfoEntity) {
					CabinEntity cabinEntity = new CabinEntity();
					cabinEntity = PlaneInfoEntityBuilder.buildCabinInfo(cabin.getString("Name"), cabinType, cabinName, tax + "", price + "", total + "", null, null, CabinEntity.class);
					PlaneInfoEntityBuilder.getSingleEntity(plane).getCabins().add(cabinEntity);
				} else if (plane instanceof DoublePlaneInfoEntity) {
					CabinEntity cabinEntity = new CabinEntity();
					cabinEntity = PlaneInfoEntityBuilder.buildCabinInfo(cabin.getString("Name"), cabinType, cabinName, tax + "", price + "", total + "", null, null, CabinEntity.class);
					PlaneInfoEntityBuilder.getDoubleEntity(plane).getCabins().add(cabinEntity);
				} else if (plane instanceof ReturnDoublePlaneInfoEntity) {
					ReturnCabinEntity cabinEntity = new ReturnCabinEntity();
					cabinEntity = PlaneInfoEntityBuilder.buildCabinInfo(cabin.getString("Name"), cabinType, cabinName, tax + "", price + "", total + "", null, null, ReturnCabinEntity.class);
					PlaneInfoEntityBuilder.getReturnDoubleEntity(plane).getReturnCabins().add(cabinEntity);
				}
			}
		}
	}

	private JSONObject getCabinPriceDetail(String cabinType, String segId) throws Exception {
		HttpRequestBase request;
		String page;
		try {
			Map<String, String> p = new HashMap<String, String>();
			p.put("GoAdultCabin", cabinType);
			p.put("GoSegId", segId);
			p.put("Lang", "zh_cn");
			p.put("flag", "0");
			request = super.getBasePost("http://www.china-sss.com/Ajax/GetFlightFees", p);
			page = super.excuteRequest(super.getHttpClient(), request, true);
			super.setLenghtCount(page.getBytes().length);
			return JSONObject.fromObject(page);
		} finally {
			request = null;
		}
	}

	private JSONArray getCabinDatas(String sid, String tid) throws Exception {
		HttpRequestBase request;
		String page;
		try {
			Map<String, String> p = new HashMap<String, String>();
			p.put("sID", sid);
			p.put("mID", "0");
			p.put("tID", tid);
			request = super.getBasePost("http://www.china-sss.com/AirFlights/GetAllPrice", p);
			page = super.excuteRequest(super.getHttpClient(), request, true);
			super.setLenghtCount(page.getBytes().length);
			return JSONArray.fromObject(page);
		} finally {
			request = null;
		}
	}

	private String getSeatName(String seatType) {
		if ("SW".equals(seatType)) {
			return "商务经济座";
		} else if ("A".equals(seatType)) {
			return taskQueue.getIsInternational() == 0 ? "绿翼自由飞" : "普通舱";
		} else {
			return taskQueue.getIsInternational() == 0 ? "轻松特价行" : "特价舱";
		}
	}
}
